package fgoScript.entity.guda;

import java.awt.*;
import java.awt.event.KeyEvent;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.List;

import com.alibaba.fastjson.JSON;
import commons.entity.Constant;
import commons.entity.CpMissonResults;
import commons.entity.NativeCp;
import commons.util.MySpringUtil;
import destinychild.entity.PointAndColor;
import fgoScript.constant.FgoPreference;
import fgoScript.entity.*;
import fgoScript.exception.AppNeedUpdateException;
import fgoScript.service.CommonMethods;
import gudaziEx.util.ChainUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import fgoScript.constant.GameConstant;
import fgoScript.constant.PointInfo;
import fgoScript.exception.AppNeedNextException;
import fgoScript.exception.AppNeedRestartException;
import fgoScript.exception.AppNeedStopException;
import fgoScript.service.AutoAct;
import fgoScript.service.EventFactors;
import commons.util.ProcessDealUtil;
import commons.util.GameUtil;
import commons.util.PropertiesUtil;

@SuppressWarnings("ALL")
public abstract class AbstractApGudazi implements InterfaceApGudazi{
    private static final Logger LOGGER = LogManager.getLogger(AbstractApGudazi.class);
    private static final FgoPreference fgoPreference = (fgoScript.constant.FgoPreference) MySpringUtil.getApplicationContext().getBean("fgoPreference");
    private static String PREFIX = GameUtil.getPreFix();
    private int retunTimes = 0;
    protected Color[][] DEFAULT_SKILL_COLORS;

    private int[] accountArray;
    private int[] apArray;
    @Override
    public void setAccountArray(int[] accountArray) {
        this.accountArray = accountArray;
    }

    @Override
    public void setApArray(int[] apArray) {
        this.apArray = apArray;
    }

    /**
     * 入口json文件路径
     */
    public String getSpecialGatesFilePath(){
        return null;
    }

    /**
     * @param accountArray
     * @param apArray
     * @throws Exception
     */
    @Override
    public void startAllFgo() throws Exception {
        int accountNum;
        int size = accountArray.length;
        int vms = 2;
        boolean ifClose = true;
        for (int i = 0; i < size; i++) {
            accountNum = accountArray[i];
            // 刷训练本
            try {
                ProcessDealUtil.killAllDnPlayer();
                GameUtil.delay(1000);
                startOneFgo(accountNum, vms, apArray);
                // 关闭所有相关应用
                closeLDForFGO(vms);
                //登录训练状态
                CpMissonResults cr = CpMissonResults.getInstance();
                boolean[] accountTrainState = cr.getAccountTrainState();
                accountTrainState[i] = true;
                ChainUtil.saveCpMissonResults(cr);
            } catch (AppNeedNextException e) {
                LOGGER.info(e.getMessage());
                GameUtil.img2file(GameConstant.IMG_EXTEND, PREFIX + "\\账号" + accountNum + "_体力不足页面.");
                continue;
            } catch (AppNeedStopException e) {
            	ifClose = false;
            	throw e;
			}finally {
				if (ifClose) {
                    closeLDForFGO(vms);
				}
			}

        }

    }
    /**
     *
     * @param accountNum 账号数字
     * @param apArray AP数组
     */
    private void startOneFgo(int accountNum, int vms, int[] apArray) throws Exception {
        int len = apArray.length;
        int apNum;//ap数字
        int appleCost = 0;
        String value = "";
        String key  = "";
        int count = 0;
        for (int i = 0; i < len; i++) {
        	apNum = apArray[i];
        	key ="hasDo" + new SimpleDateFormat("yyyy-MM-dd").format(new Date());
        	value = accountNum+"ap"+apNum;
        	String hasDo = PropertiesUtil.getValueFromHasDoFile(key);
        	if (len < 5 || i>3 || StringUtils.isBlank(hasDo) || !hasDo.contains(value)) {
        		 // 开始战斗
                LOGGER.info("账号" + accountNum + ",ap场合：" + apNum + " AP 开始");
                try {
                    startFight(accountNum, vms, apNum, false, count, len, appleCost);
                } catch (AppNeedUpdateException e) {
                    LOGGER.info("不应该更新异常！");
                    LOGGER.info(e.getMessage());
                    closeLDForFGO(vms);
                    startFight(accountNum, vms, apNum, true, count, len, appleCost);
                } finally {
                }
                //写入已经完成的 内容
                Map<String, String> map = new HashMap<>();
                if (!hasDo.contains(value)) {
                	map.put(key, StringUtils.isBlank(hasDo)?value:hasDo+value);
                	PropertiesUtil.setValueForHasDo(map);
				}
                // 结束以后需要执行的方法
                fightOverMethod();
                count++;
			}else {
				continue;
			}

        }
        GameUtil.img2file(GameConstant.IMG_EXTEND, PREFIX + "账号" + accountNum + "_结束战斗首页.");
    }
    private void closeLDForFGO(int accountNum){
        if ("RZH_SERVER".equals(NativeCp.getUserName())) {
            ProcessDealUtil.closeLDForServerFgoSpace(accountNum);
        }else {
            ProcessDealUtil.closeLD(accountNum);
        }
    }

    private void startFight(int accountNum, int vms, int apNum, boolean reStart, int i, int apLen, int appleCost) throws Exception {
        boolean continueGo = true;
        boolean rebootFlag = false;
        try {
        	if (isTopage()) {
				rebootFlag = false;
			}else {
				if (i == 0 || reStart == true) {
					// 打开账号
//                    if ("RZH_SERVER".equals(NativeCp.getUserName())) {
//                        ProcessDealUtil.startAppForServerFgoSpace(accountNum,false);
//                    }else {
//                        ProcessDealUtil.startApp(accountNum,false);
//                    }
                    ProcessDealUtil.startFgoByReplace(accountNum,vms);
					// 检测loading
					move2WinAndTransferPage(accountNum);
                    // 检测公告
                    LOGGER.info("开始检测是否重开。。。");
                    PointColor pc = CommonMethods.open2GudaOrRestart();
                    rebootFlag = pc.getColor().getRGB() == PointInfo.getInstance().getcButtonRestartYes().getRGB();
				}
			}
            if (rebootFlag) {
                LOGGER.info("重开战斗");
            } else {
                if (i == 0 || reStart == true){
                    GameUtil.waitForHomePage();
                    // 选本
                    LOGGER.info("选本");
                    try {
                        GameUtil.delay(1500);
                        GameUtil.waitInteruptSolution(0, Constant.FGOMonitor);
                        intoAndSelect(apNum, accountNum);
                    } catch (AppNeedRestartException e) {
                        if (GameUtil.likeEqualColor(PointInfo.getInstance().getcAppleNeed01(), GameUtil.getScreenPixel(PointInfo.getInstance().getpAppleNeed01())) ||
                                GameUtil.likeEqualColor(PointInfo.getInstance().getcAppleNeed02(), GameUtil.getScreenPixel(PointInfo.getInstance().getpAppleNeed02()))) {
                            if (appleCost == GameConstant.APPLE_COUNT) {
                                LOGGER.info("已达到苹果消耗量，停止更新苹果。");
                                throw new AppNeedNextException();
                            }else {
                                GameUtil.img2file(GameConstant.IMG_EXTEND, PREFIX + "\\账号" + accountNum + "_使用第"+(appleCost+1)+"个苹果.");
                                GameUtil.getMymouse().mouseMoveByPoint(PointInfo.getInstance().getpAppleNeed01(),true,true);

                                GameUtil.getMymouse().mousePressAndRelease(GameConstant.DELAY/4);
                                GameUtil.getMymouse().mouseMoveByPoint(PointInfo.getInstance().getpConnectYes(),true,true);

                                GameUtil.getMymouse().mousePressAndRelease(GameConstant.DELAY/4);
                                GameUtil.delay(GameConstant.DELAY*5);
                                LOGGER.info("ap不足，更新苹果。");
                            }
                        }else{
                            throw e;
                        }
                    }
                    // 选人
                    LOGGER.info("选人");
                    EventFactors.supportServant = getSuppotServant();
                    selectRoomPressFightForQp(accountNum, appleCost, apNum);
                    CommonMethods.waitToAttack(null, LOGGER);
                }
            }

        } catch (AppNeedRestartException e) {
            LOGGER.info("进入房间异常！");
            LOGGER.info(e.getMessage());
            closeLDForFGO(accountNum);
            startFight(accountNum, vms, apNum, true, i, apLen, appleCost);
            continueGo = false;
        }
        if (continueGo) {
            try {
                // 偏好设置
                if (i == 0 && GameConstant.IF_SET_PRE && !rebootFlag) {
                    preferenceSet();
                }
                // 战斗并且返回
                fightAndStop(rebootFlag, apNum, accountNum);
            } catch (AppNeedRestartException e) {
                LOGGER.info("战斗异常！");
                LOGGER.info(e.getMessage());
                closeLDForFGO(vms);
                startFight(accountNum,vms, apNum, true, i, apLen, appleCost);
                continueGo = false;
            }
        }
        if (continueGo) {
            try {
                // 结算材料羁绊，处理方块，返回开始界面
                startBalance(accountNum, apNum, i,appleCost);
                // 回到登录页面
//                if (i != apLen - 1) {
//                    returnTopPage();
//                    LOGGER.info("回到了首页:" + i);
//                } else {
//                    LOGGER.info("最后一页：" + i);
//                }
                if (i != apLen-1){
                    selectSupport();
                }
            } catch (AppNeedRestartException e) {
                LOGGER.info("结算，返回异常！");
                LOGGER.info(e.getMessage());
                closeLDForFGO(vms);
                startFight(accountNum,vms, apNum, true, i, apLen, appleCost);
            }
        }
    }
    private void selectSupport() throws AppNeedRestartException, AppNeedStopException, AppNeedUpdateException {
        // 选人界面点
        Point p_wait = PointInfo.getInstance().getpSupportSelect();
        Color c_wait = PointInfo.getInstance().getcSupportSelect();
        List<PointColor> pocoList = new ArrayList<PointColor>();
        pocoList.add(new PointColor(p_wait, c_wait, true));
        GameUtil.waitUntilAllColor(pocoList, GameConstant.DELAY, Constant.FGOMonitor);
        GameUtil.delay(2000);
        // 选职介
        GameUtil.getMymouse().mouseMoveByPoint(EventFactors.supportServant,true,true);

        GameUtil.getMymouse().mousePressAndRelease(GameConstant.DELAY/4);
        // 选人
        List<PointAndColor> pacList = PointInfo.getInstance().getPersonNotSelects();
        int size = pacList.size();
        PointAndColor tempPac;
        Point tempPoint;
        Color tempColor;
        Point supportLoc = null;
        for (int j = 0; j < size; j++) {
            tempPac = pacList.get(j);
            tempPoint = tempPac.getPoint();
            tempColor = tempPac.getColor();
            if(!GameUtil.likeEqualColor(tempColor,GameUtil.getScreenPixel(tempPoint),10)){
                supportLoc = tempPoint;
                break;
            }
        }
        GameUtil.getMymouse().mouseMoveByPoint(supportLoc,true,true);

        GameUtil.getMymouse().mousePressAndReleaseForConfirm(null);
        // 如果出现战斗按钮等待
        pocoList = new ArrayList<PointColor>();
        PointColor bsPC= new PointColor(PointInfo.getInstance().getpBattleStart(), PointInfo.getInstance().getcBattleStart(), true);
        PointColor baPC= new PointColor(PointInfo.getInstance().getpBlueAttack(), PointInfo.getInstance().getcBlueAttack(), true);
        pocoList.add(bsPC);
        pocoList.add(baPC);
        PointColor wPC = GameUtil.waitUntilOneColor(pocoList, Constant.FGOMonitor);
        if(bsPC.equals(wPC)){
            LOGGER.info("配置界面，开始战斗");
            // 点击开始战斗按钮
            GameUtil.getMymouse().mouseMoveByPoint(PointInfo.getInstance().getpBattleStart(),true,true);

            GameUtil.getMymouse().mousePressAndRelease(GameConstant.DELAY/4);
        }
    }
    private void selectRoomPressFightForQp(int acountNum, int appleCost, int apNum) throws Exception {
        List<PointColor> pocoList = new ArrayList<PointColor>();
        // 选人界面点
        Point p_wait = PointInfo.getInstance().getpSupportSelect();
        Color c_wait = PointInfo.getInstance().getcSupportSelect();

        // 无苹果点
 		Point p_apple_need01 = PointInfo.getInstance().getpAppleNeed01();
 		Color c_apple_need01 = PointInfo.getInstance().getcAppleNeed01();
 		Point p_apple_need02 = PointInfo.getInstance().getpAppleNeed02();
 		Color c_apple_need02 = PointInfo.getInstance().getcAppleNeed02();

        List<PointColor> pcList = new ArrayList<PointColor>();
        pcList.add(new PointColor(p_apple_need01, c_apple_need01, null, true));
		pcList.add(new PointColor(p_apple_need02, c_apple_need02, null, true));
        List<PointColor> finishPCList = new ArrayList<PointColor>();
        finishPCList.add(new PointColor(p_wait, c_wait, null, true));
        AutoAct ac = new AutoAct(pcList, finishPCList) {
            @Override
            public void doSomeThing() throws Exception {
                Color cWait = this.getPcWait().getColor();
                if (GameUtil.likeEqualColor(c_apple_need01, cWait) ||
						GameUtil.likeEqualColor(c_apple_need02, cWait)) {
                    if (appleCost == GameConstant.APPLE_COUNT) {
                        LOGGER.info("已达到苹果消耗量，停止更新苹果。");
                        throw new AppNeedNextException();
                    }else {
                        GameUtil.img2file(GameConstant.IMG_EXTEND, PREFIX + "\\账号" + acountNum + "_使用第"+(appleCost+1)+"个苹果.");
                        GameUtil.getMymouse().mouseMoveByPoint(PointInfo.getInstance().getpAppleNeed01(),true,true);

                        GameUtil.getMymouse().mousePressAndRelease(GameConstant.DELAY/4);
                        GameUtil.getMymouse().mouseMoveByPoint(PointInfo.getInstance().getpConnectYes(),true,true);

                        GameUtil.getMymouse().mousePressAndRelease(GameConstant.DELAY/4);
                        GameUtil.delay(GameConstant.DELAY*5);
                        LOGGER.info("ap不足，更新苹果。");
                    }
                }
            }
        };
        //监控短时间超时线程
  		new Thread(new AbstractWaitForOutTime() {
  			@Override
  			public void beforeDo() {
  				GameUtil.setCHECK_COUNT(0);
  			}
  			@Override
  			public void afterDo() {
  				GameUtil.setGO_FLAG(false);
  			}
  		}).start();
  		boolean flag = ac.autoAct();
  		if (!flag) {
  			if (++retunTimes == 2) {
  				retunTimes = 0;
  				throw new AppNeedRestartException();
			}
  			returnTopPage();
            GameUtil.waitForHomePage();
  			intoAndSelect(apNum, acountNum);
  			selectRoomPressFightForQp(acountNum, appleCost, apNum);
  		}else {
  			selectSupport();
  		}
    }

    /**
     *
     * @param countNum 账号数字
     * @throws Exception
     */
    public static void move2WinAndTransferPage(int countNum) throws Exception {
        // 检测异动前的FGO游戏图标{
        //		"point" : {"x" : 662, "y" : 415},
        //		"color" : {"r" : 255, "g" : 221, "b" : 0}
        //}
        Point p_left_top = PointInfo.getInstance().getpLeftTop();
        Color c_left_top = PointInfo.getInstance().getcLeftTop();
        java.util.List<PointColor> pocoList = new ArrayList<PointColor>();
        Point pRenzhehao = new Point(662,415);
        Color cRenzhehao = new Color(255,221,0);
        if(Toolkit.getDefaultToolkit().getScreenSize().width == 2560){
            pocoList.add(new PointColor(pRenzhehao, cRenzhehao, true));
        }else{
            pocoList.add(new PointColor(p_left_top, c_left_top, true));
        }
        GameUtil.waitUntilAllColor(pocoList, GameConstant.DELAY, Constant.FGOMonitor);

        // 移动窗口至左上角
        GameUtil.moveToLeftTop();

        // 检测loading是否完毕
        checkLoadingAndTransferPage(countNum);
        return;
    }

    private static void checkLoadingAndTransferPage(int countNum) throws Exception {
        List<PointColor> pcList = new ArrayList<PointColor>();
        pcList.add(new PointColor(PointInfo.getInstance().getpLoading(), PointInfo.getInstance().getcLoading(), PointInfo.getInstance().getDeadPoint(), true));
        List<PointColor> finishPCList = new ArrayList<PointColor>();
        finishPCList.add(new PointColor(PointInfo.getInstance().getpTransfer(), PointInfo.getInstance().getcTransfer(), PointInfo.getInstance().getDeadPoint(), true));
        AutoAct ac = new AutoAct(pcList, finishPCList) {
            @Override
            public void doSomeThing() {
                Color cWait = this.getPcWait().getColor();
                if (GameUtil.likeEqualColor(PointInfo.getInstance().getcTransfer(), cWait)) {
                    GameUtil.img2file(GameConstant.IMG_EXTEND, PREFIX + "\\账号" + countNum + "_引继页面.");
                }
            }
        };
        ac.autoAct();
    }

    private void preferenceSet() throws AppNeedStopException {
        // 初始化偏好
        // 偏好坐标点
        Point ph0 = fgoPreference.getLocation();// 颜色：25;55;98 Color ch0 = new Color(25, 55, 98);
        GameUtil.getMymouse().mouseMoveByPoint(ph0,true,true);

        GameUtil.getMymouse().mousePressAndRelease(GameConstant.DELAY/4);
        GameUtil.delay(2 *GameConstant.DELAY);
        // 选项坐标点
        List<Point> optionPoints = fgoPreference.getOptionPoints();
        List<String> colorStyles = fgoPreference.getColorStyles();
        int arraySize = optionPoints.size();
        Point tempPoint;
        String tempStyle;
        Color screenColor;
        for (int i = 0; i < arraySize; i++) {
            tempPoint = optionPoints.get(i);
            tempStyle = colorStyles.get(i);
            screenColor = GameUtil.getScreenPixel(tempPoint);
            if("bright".equals(tempStyle)){
                if (screenColor.getRed()>100){
                    GameUtil.getMymouse().mouseMoveByPoint(tempPoint,true,true);

                    GameUtil.getMymouse().mousePressAndRelease(GameConstant.DELAY/4);
                }
            }else{
                if (screenColor.getRed()<100){
                    GameUtil.getMymouse().mouseMoveByPoint(tempPoint,true,true);

                    GameUtil.getMymouse().mousePressAndRelease(GameConstant.DELAY/4);
                }
            }
        }
        // 死角点击
        GameUtil.getMymouse().mouseMoveByPoint(PointInfo.getInstance().getDeadPoint(),true,true);

        GameUtil.getMymouse().mousePressAndRelease(GameConstant.DELAY/4);
        // 蓝色圆板
        Point p0 = PointInfo.getInstance().getpBlueAttack();// 颜色：0;113;216 Color c1 = new Color(0, 113, 216);
        GameUtil.getMymouse().mouseMoveByPoint(p0,true,true);

        GameUtil.getMymouse().mousePressAndRelease(GameConstant.DELAY/4);
        GameUtil.delay(2 * GameConstant.DELAY);
        // 加速坐标
        // 偏中间
        Point pm = fgoPreference.getAccelerateMiddle();
        // 偏左
        Point pl = fgoPreference.getAccelerateLeft();
        List<Point> pointList = new ArrayList<>();
        pointList.add(pm);
        pointList.add(pl);
        if (GameUtil.getColorEveValue(pointList) < 180) {
            GameUtil.getMymouse().mouseMoveByPoint(pm,true,true);

            GameUtil.getMymouse().mousePressAndRelease(GameConstant.DELAY/4);
        }
        // 复位点
        Point pf = PointInfo.getInstance().getpReset();
        GameUtil.getMymouse().mouseMoveByPoint(pf,true,true);

        GameUtil.getMymouse().mousePressAndRelease(GameConstant.DELAY/4);
    }
    private void startBalance(int accountNum, int apNum, int count, int appleCost) throws Exception {
        LOGGER.info("结算侦测");
        // 选人界面点
        Point p_wait = PointInfo.getInstance().getpSupportSelect();
        Color c_wait = PointInfo.getInstance().getcSupportSelect();
        // 再战斗
        Point p_rePeat = new Point(786,269);
        // 死角点
        Point dead_point = PointInfo.getInstance().getDeadPoint();
        // 复位点
        Point p_reset = PointInfo.getInstance().getpReset();
        // 羁绊三角1
        Point p_fetter01 = PointInfo.getInstance().getpFetter01();
        Color c_fetter01 = PointInfo.getInstance().getcFetter01();
        // 羁绊三角2
        Point p_fetter02 = PointInfo.getInstance().getpFetter02();
        Color c_fetter02 = PointInfo.getInstance().getcFetter02();
        // 羁绊升级
        Point p_fetter_up = PointInfo.getInstance().getpFetterUp();
        Color c_fetter_up = PointInfo.getInstance().getcFetterUp();
        Point p_level_up = PointInfo.getInstance().getpLevelUp();
        Color c_level_up = PointInfo.getInstance().getcLevelUp();
        // 确认点
        Point p_confirm_rd = PointInfo.getInstance().getpConfirmRd();
        Color c_confirm_rd = PointInfo.getInstance().getcConfirmRd();
        // 好友申请拒绝点
  		Point p_get_friend_no = PointInfo.getInstance().getpGetFriendNo();
  		Color c_get_friend_no = PointInfo.getInstance().getcGetFriendNo();
        // 咕哒子
        Point p_guda = PointInfo.getInstance().getpGuda();
        Color c_guda = PointInfo.getInstance().getcGuda();
        // 获取奖励动态坐标颜色
        Point p_reward_action = PointInfo.getInstance().getpRewardAction();
        Color c_reward_action = PointInfo.getInstance().getcRewardAction();
        // 无苹果点
        Point p_apple_need01 = PointInfo.getInstance().getpAppleNeed01();
        Color c_apple_need01 = PointInfo.getInstance().getcAppleNeed01();
        Point p_apple_need02 = PointInfo.getInstance().getpAppleNeed02();
        Color c_apple_need02 = PointInfo.getInstance().getcAppleNeed02();
        List<PointColor> pcList = new ArrayList<PointColor>();
        pcList.add(new PointColor(p_fetter01, c_fetter01, p_reset, true));
        pcList.add(new PointColor(p_fetter02, c_fetter02, p_reset, true));
        pcList.add(new PointColor(p_fetter_up, c_fetter_up, p_reset, true));
        pcList.add(new PointColor(p_level_up, c_level_up, p_reset, true));
        pcList.add(new PointColor(p_apple_need01, c_apple_need01, null, true));
        pcList.add(new PointColor(p_apple_need02, c_apple_need02, null, true));
        pcList.add(new PointColor(p_confirm_rd, c_confirm_rd, p_confirm_rd, true));
		pcList.add(new PointColor(p_get_friend_no, c_get_friend_no, p_get_friend_no, true));
        pcList.add(new PointColor(p_guda, c_guda, p_rePeat, true));
        pcList.add(new PointColor(p_reward_action, c_reward_action, p_reward_action, true));
        // 再开加入
        pcList.add(new PointColor(PointInfo.getInstance().getpBattleReapeatYes(), PointInfo.getInstance().getcBattleReapeatYes(), PointInfo.getInstance().getpBattleReapeatYes(), true));
        List<PointColor> finishPCList = new ArrayList<PointColor>();
        finishPCList.add(new PointColor(p_wait, c_wait, dead_point, true));
        AutoAct ac = new AutoAct(pcList, finishPCList) {
            @Override
            public void doSomeThing() throws Exception {
                Color cWait = this.getPcWait().getColor();
                if (GameUtil.likeEqualColor(c_confirm_rd, cWait)) {
                    GameUtil.img2file(GameConstant.IMG_EXTEND, PREFIX + "账号" + accountNum + "_" + apNum + "ap第" +count+ "次奖励页面.");
                }
                if (GameUtil.likeEqualColor(c_apple_need01, cWait) ||
                        GameUtil.likeEqualColor(c_apple_need02, cWait)) {
                    if (appleCost == GameConstant.APPLE_COUNT) {
                        LOGGER.info("已达到苹果消耗量，停止更新苹果。");
                        throw new AppNeedNextException();
                    }else {
                        GameUtil.img2file(GameConstant.IMG_EXTEND, PREFIX + "\\账号" + accountNum + "_使用第"+(appleCost+1)+"个苹果.");
                        GameUtil.getMymouse().mouseMoveByPoint(PointInfo.getInstance().getpAppleNeed01(),true,true);

                        GameUtil.getMymouse().mousePressAndRelease(GameConstant.DELAY/4);
                        GameUtil.getMymouse().mouseMoveByPoint(PointInfo.getInstance().getpConnectYes(),true,true);

                        GameUtil.getMymouse().mousePressAndRelease(GameConstant.DELAY/4);
                        GameUtil.delay(GameConstant.DELAY*5);
                        LOGGER.info("ap不足，更新苹果。");
                    }
                }
            }
        };
        ac.autoAct();
    }
    private void returnTopPage() throws Exception {
        Point pNotice = PointInfo.getInstance().getpNoticeExit();
        Color cNotice = PointInfo.getInstance().getcNoticeExit();
        Color temp = GameUtil.getScreenPixel(pNotice);
        Point pBack = null;
        LOGGER.info("开始返回首页");
        for (int i = 0; i < 20; i++) {
            if (GameUtil.likeEqualColor(cNotice, temp)) {
                break;
            }
            pBack = PointInfo.getInstance().getpBack();
            GameUtil.getMymouse().mouseMoveByPoint(pBack,true,true);

            GameUtil.getMymouse().mousePressAndRelease(GameConstant.DELAY/4);
            GameUtil.delay(GameConstant.DELAY*2);
            temp = GameUtil.getScreenPixel(pNotice);
        }
    }
    protected final  void moveBySteps(Point start, Point end) {
        Robot r = GameUtil.getRb();
        int actor = end.getX() + end.getY() - start.getX() - start.getY() > 0 ? 1 : -1;
        if ((int) start.getX() == (int) end.getX()) {

            for (int i = (int) start.getY(); (i - end.getY()) * actor < 0; i += GameConstant.MOVE_STEP * actor) {
                r.mouseMove((int) start.getX(), i);
                if (i == (int) start.getY()) {
                    GameUtil.delay(GameConstant.DELAY);
                    mousePress(KeyEvent.BUTTON1_DOWN_MASK);
                }
                r.delay(GameConstant.MOVE_TIME);
            }
        } else {
            for (int i = (int) start.getX(); (i - end.getX()) * actor < 0; i += GameConstant.MOVE_STEP * actor) {
                r.mouseMove(i, (int) start.getY());
                if (i == (int) start.getX()) {
                    GameUtil.delay(GameConstant.DELAY);
                    mousePress(KeyEvent.BUTTON1_DOWN_MASK);
                }
                r.delay(GameConstant.MOVE_TIME);
            }
        }
        r.mouseMove((int) end.getX(), (int) end.getY());
        GameUtil.delay(GameConstant.DELAY);
        mouseRelease(KeyEvent.BUTTON1_DOWN_MASK);
    }
    private void mousePress(int key) {
        GameUtil.getRb().mousePress(key);
        GameUtil.delay(GameConstant.DELAY);
        GameUtil.delay(GameConstant.DELAY);
    }
    private void mouseRelease(int key) {
        GameUtil.getRb().mouseRelease(key);
        GameUtil.getRb().delay(GameConstant.DELAY);
        GameUtil.getRb().delay(GameConstant.DELAY);
    }

    protected final  void giveServantSkills(List<Map<String, Object>> list) throws Exception {
        Map<String, Object> tempMap = null;
        int size = list.size();
        for (int j = 0; j < size; j++) {
            tempMap = list.get(j);
            int[] skills = (int[]) tempMap.get("skills");
            fromToServantSkills((int) tempMap.get("from"),
                    (int) tempMap.get("to"), skills);
            if (skills.length!=0 && j != size-1) {
                CommonMethods.waitToAttack(null, LOGGER);
            }
        }
    }
    private void fromToServantSkills(int from,int to,int[] skill) throws Exception {
        Point[] skillPoints = new Point[skill.length];
        Point temp = null;
        int size = skill.length;
        for (int i = 0; i < size; i++) {
            int key = skill[i];
            switch (key) {
                case 0:{
                    temp = PointInfo.getInstance().getpSkill01();
                    skillPoints[i]=	new Point((int) temp.getX()
                            + GameConstant.HEAD_SPACE * from,
                            (int) temp.getY());
                    break;
                }
                case 1:{
                    temp = PointInfo.getInstance().getpSkill02();
                    skillPoints[i]=	new Point((int) temp.getX()
                            + GameConstant.HEAD_SPACE * from,
                            (int) temp.getY());
                    break;
                }
                case 2:{
                    temp = PointInfo.getInstance().getpSkill03();
                    skillPoints[i]=	new Point((int) temp.getX()
                            + GameConstant.HEAD_SPACE * from,
                            (int) temp.getY());
                    break;
                }
                default:{
                    break;
                }
            }
        }
        Point toPerson = null;
        switch (to) {
            case 0:{
                toPerson = PointInfo.getInstance().getSkillPerson01();
                break;
            }
            case 1:{
                toPerson = PointInfo.getInstance().getSkillPerson02();
                break;
            }
            case 2:{
                toPerson = PointInfo.getInstance().getSkillPerson03();
                break;
            }
            default:{
                break;
            }
        }
        int num =skillPoints.length;
        for (int i = 0; i < num; i++) {
            GameUtil.getMymouse().mouseMoveByPoint(skillPoints[i],true,true);

            GameUtil.getMymouse().mousePressAndRelease(GameConstant.DELAY/6);

            // 选择人物
            GameUtil.getMymouse().mouseMoveByPoint(toPerson,true,true);

            GameUtil.getMymouse().mousePressAndRelease(GameConstant.DELAY/6);

            GameUtil.getMymouse().mouseMoveByPoint(PointInfo.getInstance().getDeadPoint(),true,true);

            GameUtil.getMymouse().mousePressAndRelease(GameConstant.DELAY/6);
            if (i != num - 1) {
                // 等待
                CommonMethods.waitToAttack(null, LOGGER);
            }
        }
    }
    protected final  void giveClothSkills(List<Map<String, Object>> list) throws Exception {
        Map<String, Object> tempMap = null;
        int size = list.size();
        for (int j = 0; j < size; j++) {
            tempMap = list.get(j);
            fromToClothSkills((int) tempMap.get("to"),
                    (int[]) tempMap.get("skills"));
            if (j != size-1) {
                CommonMethods.waitToAttack(null, LOGGER);
            }
        }
    }
    private void fromToClothSkills(int to,int[] skill) throws Exception {
        Point[] skillPoints = new Point[skill.length];
        int size = skill.length;
        for (int i = 0; i < size; i++) {
            int key = skill[i];
            switch (key) {
                case 0:{
                    skillPoints[i]=	PointInfo.getInstance().getpClothSkill01();
                    break;
                }
                case 1:{
                    skillPoints[i]=	PointInfo.getInstance().getpClothSkill02();
                    break;
                }
                case 2:{
                    skillPoints[i]=	PointInfo.getInstance().getpClothSkill03();
                    break;
                }
                default:{
                    break;
                }
            }
        }
        Point toPerson = null;
        switch (to) {
            case 0:{
                toPerson = PointInfo.getInstance().getSkillPerson01();
                break;
            }
            case 1:{
                toPerson = PointInfo.getInstance().getSkillPerson02();
                break;
            }
            case 2:{
                toPerson = PointInfo.getInstance().getSkillPerson03();
                break;
            }
            default:{
                break;
            }
        }
        int num = skillPoints.length;
        for (int i = 0; i < num; i++) {
            // 选择衣服，技能
            GameUtil.getMymouse().mouseMoveByPoint(PointInfo.getInstance().getpCloth(),true,true);

            GameUtil.getMymouse().mousePressAndRelease(GameConstant.DELAY/6);
            GameUtil.getMymouse().mouseMoveByPoint(skillPoints[i],true,true);

            GameUtil.getMymouse().mousePressAndRelease(GameConstant.DELAY/6);

            // 选择人物
            GameUtil.getMymouse().mouseMoveByPoint(toPerson,true,true);

            GameUtil.getMymouse().mousePressAndRelease(GameConstant.DELAY/6);

            GameUtil.getMymouse().mouseMoveByPoint(PointInfo.getInstance().getDeadPoint(),true,true);

            GameUtil.getMymouse().mousePressAndRelease(GameConstant.DELAY/6);
            if (i != num - 1) {
                // 等待
                CommonMethods.waitToAttack(null, LOGGER);
            }
        }
    }
    protected boolean checkFinish(){
        boolean flag = false;
        List<Point> pointList = new ArrayList<>();
        List<Color> colorList = new ArrayList<>();
        // 羁绊三角1
        // 羁绊三角2
        // 羁绊三角3
        // 羁绊升级
        // 等级升级
        // 确认点
        pointList.add(PointInfo.getInstance().getpFetter01());
        pointList.add(PointInfo.getInstance().getpFetter02());
        pointList.add(PointInfo.getInstance().getpFetter03());
        pointList.add(PointInfo.getInstance().getpFetterUp());
        pointList.add(PointInfo.getInstance().getpLevelUp());
        pointList.add(PointInfo.getInstance().getpConfirmRd());

        colorList.add(PointInfo.getInstance().getcFetter01());
        colorList.add(PointInfo.getInstance().getcFetter02());
        colorList.add(PointInfo.getInstance().getcFetter03());
        colorList.add(PointInfo.getInstance().getcFetterUp());
        colorList.add(PointInfo.getInstance().getcLevelUp());
        colorList.add(PointInfo.getInstance().getcConfirmRd());
        int size = colorList.size();

        Point tempP;
        Color tempC;
        Color nowColor;
        for (int i = 0; i < size; i++) {
            tempP = pointList.get(i);
            tempC = colorList.get(i);
            nowColor = GameUtil.getScreenPixel(tempP);
            if (GameUtil.likeEqualColor(tempC, nowColor)) {
                flag = true;
                break;
            }
        }
        return flag;
    }
    private void attackAAA(Comparator<CommonCard> comp) throws Exception {
        // 蓝色圆板
        Point p0 = new Point(1171, 697);// 颜色：0;113;216 Color c1 = new Color(0, 113, 216);
        GameUtil.getMymouse().mouseMoveByPoint(p0,true,true);

        GameUtil.getMymouse().mousePressAndRelease(GameConstant.DELAY/6);
        // 等待一会儿
        GameUtil.delay(GameConstant.DELAY * 4);
        Map<String, List<CommonCard>> scMap = CommonMethods.getWeakCommondCards(comp, LOGGER);
        List<CommonCard> trueList = scMap.get("trueList");

        int size = trueList.size();
        for (int i = 0; i < 3; i++) {
            GameUtil.getMymouse().mouseMoveByPoint(trueList.get(i).getpLoc(),true,true);

            GameUtil.getMymouse().mousePressAndRelease(GameConstant.DELAY/6);

        }
        CommonMethods.checkExitCardSelect();
    }
    private boolean isTopage() {
		Point p_guda = PointInfo.getInstance().getpGuda();
		Color c_guda = PointInfo.getInstance().getcGuda();
		Color Temp = GameUtil.getScreenPixel(p_guda);
		if (GameUtil.likeEqualColor(Temp, c_guda)) {
			return true;
		}
		return false;
	}

    protected GatesInfo getSpecialGatesInfo(){
        String filepath = getSpecialGatesFilePath();
        String jsonString = GameUtil.getJsonString(filepath);
        GatesInfo gi = JSON.parseObject(jsonString, GatesInfo.class);
        return gi;
    }
}
